/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package trab_sd;

import java.util.*;
import java.net.*;
import java.io.*;

public class UserListSender implements Runnable {
	
	private User localUser;
	private UserID dst;
	private Socket connection;
	private ObjectInputStream in;
	private ObjectOutputStream out;
	private boolean cont;
	
	//construtor
	public UserListSender( User localUser, UserID dst ) {
		
		//recebe o usuario e o endereco do receptor
		this.localUser = localUser;
		this.dst = dst;
		
		try {
			cont = true;
			//cria a conexao com o receptor
			this.connection = new Socket( dst.getName(), dst.getPort() );
			//configura tempo de timeout
			this.connection.setSoTimeout(50000);
			//abre os streams
			this.out = new ObjectOutputStream( this.connection.getOutputStream() );
			this.out.flush();
			this.in = new ObjectInputStream( this.connection.getInputStream() );
			
			if (out == null || in == null ) {
				System.out.println("Erro ao enviar Lista de usuarios. Tente repetir a operacao atraves do comando \"lu\".");
				cont = false;
			}
			
		}
		catch ( SocketTimeoutException | ConnectException ste) {
			if ( dst.equals(localUser.getServerID()) ) {
				localUser.removeOfflineUser(dst);
			}
			else {
				OfflineUserMsg of = new OfflineUserMsg( dst, localUser.getServerID());
				of.run();
			}
			cont = false;
		}
		catch ( UnknownHostException uhe ) {
			System.out.println("USERLISTSENDER_UHE");
			uhe.printStackTrace();
			cont = false;
		}
		catch ( IOException ioe ) {
			System.out.println("USERLISTSENDER_IOE");
			ioe.printStackTrace();
			cont = false;
		}
	}
	
	public void run() {
		try {
			
			if (cont == false) return;
			
			//Envia mensagem de envio de lista
			out.writeUTF("SENDING_USER_LIST");
			out.flush();
			//Espera confirmacao
			if ( !in.readUTF().equals("OK") ) {
				//se nao houver confirmacao, fecha conexao
				throw new SocketTimeoutException();			//MUDAR TIPO DE EXCESSAO
			}
			//envia a lista
			out.writeObject( localUser.getUserList() );
			out.flush();
			//envia mensagem de termino de envio
			out.writeUTF("FINISHED");
			out.flush();
			//fecha streams
			in.close();
			out.close();
			//fecha conexao
			connection.close();
		}
		
		catch ( ConnectException ste) {
			if ( dst.equals(localUser.getServerID()) ) {
				localUser.removeOfflineUser(dst);
			}
			else {
				OfflineUserMsg of = new OfflineUserMsg( dst, localUser.getServerID());
				of.run();
			}
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
		}
		finally {
			try {
				//fecha streams
				if ( in != null ) {
				in.close();
				}
				if (out != null) {
				out.close();
				}
				//fecha conexao
				if (connection != null)
				connection.close();
			}
			catch (Exception vsf) {
				//System.out.println("USERLISTSENDER_STE_E");
				vsf.printStackTrace();
			}
		}
	}
}
